package vn.com.pavibook.service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import vn.com.pavibook.dao.AccountDao;
import vn.com.pavibook.dao.AccountTypeDao;
import vn.com.pavibook.dao.CustomerDao;
import vn.com.pavibook.domain.model.Account;
import vn.com.pavibook.domain.model.Customer;
import vn.com.pavibook.domain.model.SearchResult;
import vn.com.pavibook.model.vo.CustomerVO;
import vn.com.pavibook.utils.GenerateMD5;

@Service
public class CustomerService {
	private static final Logger logger = LoggerFactory.getLogger(CustomerService.class);
	private static final String DATE_PATTERN = "(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/((19|20)\\d\\d)";
	@Autowired
	private AccountDao accountDao;
	
	@Autowired
	private AccountTypeDao accountTypeDao;
	
	@Autowired
	private CustomerDao customerDao;
	private Pattern pattern;
	private Matcher matcher;

	public CustomerService() {
		pattern = Pattern.compile(DATE_PATTERN);
	}
	public boolean checkExistedUsername(String username){
		return accountDao.checkExistedUsername(username);
	}
	
	public int createAccount(Account account){
		return accountDao.insertNewAccount(account);
	}
	public int getAccountTypeIdByName(String role){
		return accountTypeDao.getAccountTypeByRole(role);
	}
	
	public void createNewCustomer(CustomerVO customerVO){
		Customer customer = new Customer();
		customer = convertToCustomer(customerVO);
		customerDao.createNewCustomer(customer);
	}
	
	public Account getAccountById(int id){
		return accountDao.getAccountById(id);
	}
	
	public void updateCustomerProfile(CustomerVO customerVO){
		customerDao.updateCustomerProfile(convertToCustomer(customerVO));
	}
	
	public void updateAmountOfCustomer(Customer customer){
		customerDao.updateAmountOfCustomer(customer);
	}
	
	public boolean checkOldPassword(String oldPass, int accountId){
		Account oldAcc = accountDao.getAccountById(accountId);
		String oldPassword = oldAcc.getPassword();
		oldPass = GenerateMD5.MD5(oldPass);
		if (oldPassword.equals(oldPass)) {
			return true;
		}
		return false;
	}
	
	public void updateAccountCustomer(Account account){
		accountDao.updateAccount(account);
	}
	public Customer getCustomerByUsername(String username){
		SearchResult<Customer> result = customerDao.getCustomerByUsername(username);
		if(result.getSearchResult().size() == 0) return null;
		return result.getSearchResult().get(0);
	}
	public CustomerVO getCustomerVOByUsername(String username){
		CustomerVO customerVO = new CustomerVO();
		Customer cus = getCustomerByUsername(username);
		if(cus == null) return new CustomerVO();
		customerVO = convertToCustomerVO(cus);
		return customerVO;
	}
	
	public CustomerVO convertToCustomerVO (Customer customer){
		CustomerVO cus = new CustomerVO();
		cus.setId(customer.getId());
		cus.setAccountId(customer.getAccountId());
		cus.setFirstname(customer.getFirstname());
		cus.setLastname(customer.getLastname());
		cus.setMiddle(customer.getMiddle());
		cus.setEmail(customer.getEmail());
		cus.setActive(customer.getActive());
		cus.setBirthday(convertToDateString(customer.getBirthday()));
		cus.setGender(customer.getGender());
		cus.setAddress(customer.getAddress());
		cus.setPhone(customer.getPhone());
		cus.setPointCart(customer.getPointCart()); 
		cus.setCountry(customer.getCountry());
		return cus;
	}
	
	public Customer convertToCustomer (CustomerVO customerVO){
		Customer cus = new Customer();
		if(customerVO.getId() != null){
			cus.setId(customerVO.getId());
		}
		cus.setAccountId(customerVO.getAccountId());
		cus.setFirstname(customerVO.getFirstname());
		cus.setLastname(customerVO.getLastname());
		cus.setMiddle(customerVO.getMiddle());
		cus.setEmail(customerVO.getEmail());
		cus.setActive(customerVO.isActive());
		cus.setBirthday(convertToDate(customerVO.getBirthday()));
		cus.setGender(customerVO.getGender());
		cus.setAddress(customerVO.getAddress());
		cus.setPhone(customerVO.getPhone());
		cus.setPointCart(customerVO.getPointCart()); 
		cus.setCountry(customerVO.getCountry());
		return cus;
	}
	
	public Date convertToDate(String date){
		SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
		try {
			return dateFormat.parse(date);
		} catch (ParseException e) {
			logger.info("convertToDate: " + e.getMessage());
			return new Date();
		}
	}
	
	public String convertToDateString(Date date){
		SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
		String currentDate = dateFormat.format(date);
		return currentDate;
	}
	
	public void deleteAccountById(int id){
		accountDao.deleteAccount(id);
	}
	
	/**
	 * Validate date format with regular expression
	 * 
	 * @param date
	 *            date address for validation
	 * @return true valid date fromat, false invalid date format
	 */
	public boolean validateDate(final String date) {
		matcher = pattern.matcher(date);
		if (matcher.matches()) {
			matcher.reset();
			if (matcher.find()) {
				String day = matcher.group(1);
				String month = matcher.group(2);
				int year = Integer.parseInt(matcher.group(3));
				if (day.equals("31")
						&& (month.equals("4") || month.equals("6")
								|| month.equals("9") || month.equals("11")
								|| month.equals("04") || month.equals("06") || month
									.equals("09"))) {
					return false; // only 1,3,5,7,8,10,12 has 31 days
				} else if (month.equals("2") || month.equals("02")) {
					// leap year
					if (year % 4 == 0) {
						if (day.equals("30") || day.equals("31")) {
							return false;
						} else {
							return true;
						}
					} else {
						if (day.equals("29") || day.equals("30")
								|| day.equals("31")) {
							return false;
						} else {
							return true;
						}
					}
				} else {
					return true;
				}
			} else {
				return false;
			}
		} else {
			return false;
		}
	}
}
